package co.gov.medellin.ssti.sub.model.dao.impl;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import oracle.jdbc.OracleTypes;
import co.gov.medellin.ssti.sub.model.dao.IRepDetBeneficiarioDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.vo.BeneficiarioVO;
import co.gov.medellin.ssti.sub.model.vo.CondicionConsultaVO;
import co.gov.medellin.ssti.sub.model.vo.RepAtributoVO;
import co.gov.medellin.ssti.sub.model.vo.RepDetBeneficiarioVO;

/**
 * Clase es la implementacion de la interfaz IRepDetBeneficiarioDAO.
 * 
 * @author Consultsoft4
 * 
 */
public class RepDetBeneficiarioDAOImpl extends BaseDAOImpl implements
		IRepDetBeneficiarioDAO {
	private static final String SELECT_COUNT_BENEFICIARIOS = "SELECT COUNT(1) "
			+ " FROM(SELECT TO_CHAR(beneotor.FECHA_BENEFICIO,'DD/MM/RRRR') fechabeneficio, "
			+ " beneotor.CODIGO codbeneotor, beneotor.BEN_CODIGO codbeneficiario, "
			+ " sede.CODIGO codsede, "
			+ " sede.NOMBRE nomsede, prog.CODIGO codpro, prog.NOMBRE nompro, "
			+ " subpro.CODIGO codsubpro, subpro.NOMBRE nomsubpro "
			+ " FROM TCS_BEN_PROGRAMA prog, TCS_BEN_SUBPROGRAMA subpro, "
			+ " TCS_BEN_BENEFICIO_OTORGADO beneotor, TCS_BEN_SEDE sede, "
			+ " TCS_BEN_BENEFICIARIO beneficiario "
			+ " WHERE beneotor.SBPR_CODIGO = subpro.CODIGO "
			+ " AND beneotor.SEDE_CODIGO = sede.CODIGO "
			+ " AND subpro.PRG_CODIGO = prog.CODIGO "
			+ " AND beneficiario.CODIGO = beneotor.BEN_CODIGO "
			+ " AND beneotor.FECHA_BENEFICIO <= sysdate "
			+ " AND prog.vigencia='A' and subpro.vigencia='A' ";

	private static final String CALL_CANTIDAD_BENEFICIARIOS = "{call beneficios.PCS_CANTIDAD_BENEFICIARIOS(?, '' , ?, ?, ?, ?, ?, ?)}";
	private static final String CALL_REPORTE_BENEFICIARIOS = "{call beneficios.PCS_REPORTE_BENEFICIARIOS(?, ?, ?, ?, ?, ?, ?, ?)}";
	private static final String SELECT_NOMBRE_SEDE_BY_CODIGO = "SELECT NOMBRE FROM TCS_BEN_SEDE WHERE CODIGO = ? ";
	private static final String SELECT_NOMBRE_PROGRAMA_BY_CODIGO = "SELECT NOMBRE FROM TCS_BEN_PROGRAMA WHERE CODIGO = ? ";
	private static final String SELECT_NOMBRE_SUBPROGRAMA_BY_CODIGO = "SELECT NOMBRE FROM TCS_BEN_SUBPROGRAMA WHERE CODIGO = ? ";

	public RepDetBeneficiarioDAOImpl(Connection con) {
		super(con);
	}

	public int findCantidadBeneficiariosByCriteria(RepDetBeneficiarioVO criteria)
			throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		List<Object> parameters = new ArrayList<Object>();
		StringBuffer query = new StringBuffer(SELECT_COUNT_BENEFICIARIOS);
		int cantidad = 0;

		if ((Object) criteria.getCodeSede() != null) {
			query.append(" AND sede.CODIGO = ? ");
			parameters.add(criteria.getCodeSede());
		}
		if ((Object) criteria.getCodeSubprograma() != null) {
			query.append(" AND subpro.CODIGO = ? ");
			parameters.add(criteria.getCodeSubprograma());
		}
		if ((Object) criteria.getCodePrograma() != null) {
			query.append(" AND prog.CODIGO = ? ");
			parameters.add(criteria.getCodePrograma());
		}
		if ((Object) criteria.getDesde() != null
				&& (Object) criteria.getHasta() != null) {
			query.append(" AND beneotor.FECHA_BENEFICIO BETWEEN TO_DATE(?, 'dd/mm/rrrr')"
					+ "AND TO_DATE(?,'dd/mm/rrrr')");
			parameters.add(criteria.getDesde());
			parameters.add(criteria.getHasta());

		}
		query.append(" ORDER BY prog.NOMBRE,subpro.NOMBRE,sede.NOMBRE )");

		try {
			pstmt = conn.prepareStatement(query.toString());
			pstmt = setQueryParameters(pstmt, parameters);
			rst = pstmt.executeQuery();
			if (rst.next()) {
				cantidad = rst.getInt(1);
			}
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rst, pstmt);
		}
		return cantidad;
	}

	public Integer findCantidadBeneficiariosByFiltrosAndCriteria(
			List<CondicionConsultaVO> filtros, RepDetBeneficiarioVO criteria)
			throws DAOException {
		CallableStatement cs = null;
		ResultSet rs = null;

		String filtrosGenerales = "'"
				+ checkFiltros((Collection<CondicionConsultaVO>) filtros) + "'";
		String desde = null;
		String hasta = null;
		if (criteria != null) {
			if (criteria.getDesde() != null && !criteria.getDesde().isEmpty()) {
				desde = criteria.getDesde();
			}
			if (criteria.getHasta() != null && !criteria.getHasta().isEmpty()) {
				hasta = criteria.getHasta();
			}
		}
		try {
			String strSql = "{call beneficios.PCS_CANTIDAD_BENEFICIARIOS(" + ""
					+ filtrosGenerales + ", '' , " + criteria.getCodeSede()
					+ ", " + criteria.getCodeSubprograma() + ", "
					+ criteria.getCodePrograma() + "," + desde + ", " + hasta
					+ ", ?)}";
			cs = conn.prepareCall(strSql);
			cs.registerOutParameter(1, OracleTypes.CURSOR);
			cs.execute();
			rs = (ResultSet) cs.getObject(1);
			rs.next();
			return (new Integer(rs.getInt(1)));

			/*
			 * cs = conn.prepareCall(CALL_CANTIDAD_BENEFICIARIOS);
			 * cs.setString(1, filtrosGenerales); cs.setString(2,
			 * criteria.getCodeSede() == null ? "" : criteria
			 * .getCodeSede().toString()); cs.setString(3,
			 * criteria.getCodeSubprograma() == null ? "" :
			 * criteria.getCodeSubprograma().toString()); cs.setString(4,
			 * criteria.getCodePrograma() == null ? "" : criteria
			 * .getCodePrograma().toString()); cs.setString(5, desde);
			 * cs.setString(6, hasta); cs.registerOutParameter(7,
			 * OracleTypes.CURSOR); cs.execute();
			 * 
			 * rs = (ResultSet) cs.getObject(7); rs.next(); return (new
			 * Integer(rs.getInt(1)));
			 */
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rs, cs);
		}
	}

	public Collection<BeneficiarioVO> findReporte(
			Collection<RepAtributoVO> atributosGenericos,
			Collection<CondicionConsultaVO> filtros,
			RepDetBeneficiarioVO criteria) throws DAOException {
		CallableStatement cs = null;
		ResultSet rst = null;

		Collection<BeneficiarioVO> beneficiarios = new LinkedList<BeneficiarioVO>();
		List<RepAtributoVO> latributosGenericos = (List<RepAtributoVO>) atributosGenericos;

		RepAtributoVO atrVO = null;

		StringBuffer atriGenerales = new StringBuffer();
		String filtrosGenerales = checkFiltros(filtros);
		String desde = null;
		String hasta = null;
		if (criteria != null) {
			if (criteria.getDesde() != null && !criteria.getDesde().isEmpty()) {
				desde = criteria.getDesde();
			}
			if (criteria.getHasta() != null && !criteria.getHasta().isEmpty()) {
				hasta = criteria.getHasta();
			}
		}

		if (latributosGenericos.size() > 0) {
			for (int i = 0; i < latributosGenericos.size(); i++) {
				atrVO = (RepAtributoVO) latributosGenericos.get(i);
				atriGenerales.append(atrVO.getNombre() + "|");
			}

		}
		try {
			String strSql = "{call beneficios.PCS_REPORTE_BENEFICIARIOS('"
					+ atriGenerales + "', " + "'" + filtrosGenerales + "', "
					+ criteria.getCodeSede() + ", "
					+ criteria.getCodeSubprograma() + ", "
					+ criteria.getCodePrograma() + ", " + desde + ", " + hasta
					+ ", ? )}";
			System.out.println(strSql);
			cs = conn.prepareCall(strSql);
			cs.registerOutParameter(1, OracleTypes.CURSOR);
			cs.execute();
			rst = (ResultSet) cs.getObject(1);
			/*
			 * cs = conn.prepareCall(CALL_REPORTE_BENEFICIARIOS);
			 * cs.setString(1, atriGenerales.toString()); cs.setString(2,
			 * filtrosGenerales); cs.setString(3, criteria.getCodeSede() == null
			 * ? "" : criteria .getCodeSede().toString()); cs.setString(4,
			 * criteria.getCodeSubprograma() == null ? "" :
			 * criteria.getCodeSubprograma().toString()); cs.setString(5,
			 * criteria.getCodePrograma() == null ? "" : criteria
			 * .getCodePrograma().toString()); cs.setString(6, desde);
			 * cs.setString(7, hasta); cs.registerOutParameter(8,
			 * OracleTypes.CURSOR); cs.execute();
			 * 
			 * rst = (ResultSet) cs.getObject(8);
			 */
			BeneficiarioVO beneficiarioVO = null;

			while (rst.next()) {
				beneficiarioVO = new BeneficiarioVO();
				if (atriGenerales != null) {
					if (atriGenerales.indexOf("TIPO_DOCUMENTO") != -1) {
						beneficiarioVO.setTipoDocumento(rst
								.getString("TIPO_DOCUMENTO"));
					}
					if (atriGenerales.indexOf("NUMERO_DOCUMENTO") != -1) {
						beneficiarioVO.setNumeroDocumento(rst
								.getString("NUMERO_DOCUMENTO"));
					}
					if (atriGenerales.indexOf("PRIMER_NOMBRE") != -1) {
						beneficiarioVO.setNombre1(rst
								.getString("PRIMER_NOMBRE"));
					}
					if (atriGenerales.indexOf("SEGUNDO_NOMBRE") != -1) {
						beneficiarioVO.setNombre2(rst
								.getString("SEGUNDO_NOMBRE"));
					}
					if (atriGenerales.indexOf("PRIMER_APELLIDO") != -1) {
						beneficiarioVO.setPrimerApellido(rst
								.getString("PRIMER_APELLIDO"));
					}
					if (atriGenerales.indexOf("SEGUNDO_APELLIDO") != -1) {
						beneficiarioVO.setSegundoApellido(rst
								.getString("SEGUNDO_APELLIDO"));
					}
					if (atriGenerales.indexOf("DIRECCION_DESCRIPTIVA") != -1) {
						beneficiarioVO.setDirDescriptiva(rst
								.getString("DIRECCION_DESCRIPTIVA"));
					}
					if (atriGenerales.indexOf("DIRECCION_ENCASILLADA") != -1) {
						beneficiarioVO.setDirEncasillada(rst
								.getString("DIRECCION_ENCASILLADA"));
					}
					if (atriGenerales.indexOf("SEXO") != -1) {
						beneficiarioVO.setSexo(rst.getString("SEXO"));
					}
					if (atriGenerales.indexOf("FECHA_NACIMIENTO") != -1) {
						beneficiarioVO.setFechaNacimiento(rst
								.getString("FECHA_NACIMIENTO"));
					}
					if (atriGenerales.indexOf("VFL_CODIGO_COMUNA") != -1) {
						beneficiarioVO.setVflComuna(rst
								.getString("VFL_CODIGO_COMUNA"));
					}
					if (atriGenerales.indexOf("VFL_CODIGO_ZONA") != -1) {
						beneficiarioVO.setDescZona(rst
								.getString("VFL_CODIGO_ZONA"));
					}
					if (atriGenerales.indexOf("LOCALIZACION_COBAMA") != -1) {
						beneficiarioVO.setCobama(rst
								.getString("LOCALIZACION_COBAMA"));
					}
					if (atriGenerales.indexOf("VFL_CODIGO_BARRIO") != -1) {
						beneficiarioVO.setDescBarrio(rst
								.getString("VFL_CODIGO_BARRIO"));
					}
					if (atriGenerales.indexOf("TELEFONO") != -1) {
						beneficiarioVO.setTelefono(rst.getString("TELEFONO"));
					}
					if (atriGenerales.indexOf("ETNIA") != -1) {
						beneficiarioVO.setEtnia(rst.getString("ETNIA"));
					}
					if (atriGenerales.indexOf("CORREO_ELECTRONICO") != -1) {
						beneficiarioVO.setMail(rst
								.getString("CORREO_ELECTRONICO"));
					}
					if (atriGenerales.indexOf("FICHA_SISBEN") != -1) {
						beneficiarioVO.setFichaSisben(rst
								.getString("FICHA_SISBEN"));
					}
					if (atriGenerales.indexOf("HOGAR_SISBEN") != -1) {
						beneficiarioVO.setHogar(rst.getString("HOGAR_SISBEN"));
					}
					if (atriGenerales.indexOf("ORDEN_SISBEN") != -1) {
						beneficiarioVO.setOrdenSisben(rst
								.getString("ORDEN_SISBEN"));
					}
					if (atriGenerales.indexOf("NIVEL_SISBEN") != -1) {
						beneficiarioVO.setNivelSisben(rst
								.getString("NIVEL_SISBEN"));
					}
					if (atriGenerales.indexOf("PUNTAJE_SISBEN") != -1) {
						beneficiarioVO.setPuntajeSisben(rst
								.getString("PUNTAJE_SISBEN"));
					}
					if (atriGenerales.indexOf("FE_ENCUESTA_SISBEN") != -1) {
						beneficiarioVO.setFechaEncuesta(rst
								.getString("FE_ENCUESTA_SISBEN"));
					}
					if (atriGenerales.indexOf("DISCAPACIDAD_SISBEN") != -1) {
						beneficiarioVO.setDiscapacidad(rst
								.getString("DISCAPACIDAD_SISBEN"));
					}
					if (atriGenerales.indexOf("EDAD") != -1) {
						beneficiarioVO.setEdad(rst.getString("EDAD"));
					}
					if (criteria.getCodePrograma() == null
							&& criteria.getCodeSubprograma() == null
							&& criteria.getCodeSede() != null) {
						beneficiarioVO.setPrograma(rst
								.getString("NOMBRE_PROGRAMA"));
						beneficiarioVO.setBeneficio(rst
								.getString("NOMBRE_SUBPROGRAMA"));

					} else if (criteria.getCodePrograma() != null
							&& criteria.getCodeSubprograma() == null) {
						beneficiarioVO.setBeneficio(rst
								.getString("NOMBRE_SUBPROGRAMA"));
					}
				}

				beneficiarios.add(beneficiarioVO);
			}

		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rst, cs);
		}

		return beneficiarios;
	}

	public RepDetBeneficiarioVO findFiltros(
			RepDetBeneficiarioVO repDetBeneficiarioVO) throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String consulta = null;

		if (repDetBeneficiarioVO.getCodeSede() != null) {
			consulta = SELECT_NOMBRE_SEDE_BY_CODIGO;
			try {
				pstmt = conn.prepareStatement(consulta);
				pstmt.setLong(1, repDetBeneficiarioVO.getCodeSede().longValue());
				rst = pstmt.executeQuery();
				if (rst.next()) {
					repDetBeneficiarioVO.setNombreSede(rst.getString("NOMBRE"));
				}
			} catch (SQLException e) {
				throw new DAOException(e);
			} finally {
				close(rst, pstmt);
			}
		}
		if (repDetBeneficiarioVO.getCodePrograma() != null) {
			consulta = SELECT_NOMBRE_PROGRAMA_BY_CODIGO;
			try {
				pstmt = conn.prepareStatement(consulta);
				pstmt.setLong(1, repDetBeneficiarioVO.getCodePrograma()
						.longValue());
				rst = pstmt.executeQuery();
				if (rst.next()) {
					repDetBeneficiarioVO.setNombrePrograma(rst
							.getString("NOMBRE"));
				}
			} catch (SQLException e) {
				throw new DAOException(e);
			} finally {
				close(rst, pstmt);
			}
		}
		if (repDetBeneficiarioVO.getCodeSubprograma() != null) {
			consulta = SELECT_NOMBRE_SUBPROGRAMA_BY_CODIGO;
			try {
				pstmt = conn.prepareStatement(consulta);
				pstmt.setLong(1, repDetBeneficiarioVO.getCodeSubprograma()
						.longValue());
				rst = pstmt.executeQuery();
				if (rst.next()) {
					repDetBeneficiarioVO.setNombreSubprograma(rst
							.getString("NOMBRE"));
				}
			} catch (SQLException e) {
				throw new DAOException(e);
			} finally {
				close(rst, pstmt);
			}
		}
		return repDetBeneficiarioVO;
	}

	private String checkFiltros(Collection<CondicionConsultaVO> filtros) {
		List<CondicionConsultaVO> lFiltros = (List<CondicionConsultaVO>) filtros;
		CondicionConsultaVO filtro = null;
		StringBuffer retorno = new StringBuffer();
		if ((Object) filtros != null) {
			for (int i = 0; i < lFiltros.size(); i++) {
				filtro = lFiltros.get(i);
				String operador = filtro.getCodFiltro();
				String tipoDato = filtro.getTipoCampo();

				if (filtro.getOrigen().equals("G")) {
					retorno.append(" AND ");
					if (tipoDato.equals("N")) {
						if (operador.equals("=")) {
							retorno.append(" ben." + filtro.getCodcampo() + " "
									+ operador + " " + filtro.getValor());
						} else if (operador.equals("<>")) {
							retorno.append(" ben." + filtro.getCodcampo() + " "
									+ operador + " " + filtro.getValor());
						} else if (operador.equals("<=")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " " + filtro.getValor());
						} else if (operador.equals(">=")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " " + filtro.getValor());
						} else if (operador.equals("<")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " " + filtro.getValor());
						} else if (operador.equals(">")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " " + filtro.getValor());
						} else {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " " + filtro.getValor()
									+ " and " + filtro.getValor2());
						}
					} else if (tipoDato.equals("F")) {
						if (operador.equals("between") || operador.equals("=")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " to_date(''"
									+ filtro.getValor()
									+ "'', ''DD/MM/RRRR'') and to_date(''"
									+ filtro.getValor2()
									+ "'', ''DD/MM/RRRR'')");
						} else {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " to_date(''"
									+ filtro.getValor() + "'', ''DD/MM/RRRR'')");
						}
					} else if (tipoDato.equals("A") || tipoDato.equals("L")) {
						if (operador.equals("=")) {
							retorno.append(" UPPER(ben." + filtro.getCodcampo()
									+ " ) " + operador + " ''"
									+ filtro.getValor().toUpperCase() + "''");
						} else if (operador.equals("<>")) {
							retorno.append(" UPPER(ben." + filtro.getCodcampo()
									+ " ) " + operador + " ''"
									+ filtro.getValor().toUpperCase() + "''");
						} else if (operador.equals("like")) {
							retorno.append(" UPPER(ben." + filtro.getCodcampo()
									+ " ) " + operador + " ''%"
									+ filtro.getValor().toUpperCase() + "%''");
						}
					} else {
						if (operador.equals("=")) {
							retorno.append(" ben." + filtro.getCodcampo() + " "
									+ operador + " ''" + filtro.getValor()
									+ "''");
						} else if (operador.equals("<>")) {
							retorno.append(" ben." + filtro.getCodcampo() + " "
									+ operador + " ''" + filtro.getValor()
									+ "''");
						} else if (operador.equals("<=")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " ''" + filtro.getValor()
									+ "''");
						} else if (operador.equals(">=")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " ''" + filtro.getValor()
									+ "''");
						} else if (operador.equals("<")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " ''" + filtro.getValor()
									+ "''");
						} else if (operador.equals(">")) {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " ''" + filtro.getValor()
									+ "''");
						} else {
							retorno.append("ben." + filtro.getCodcampo() + " "
									+ operador + " ''" + filtro.getValor()
									+ "'' and ''" + filtro.getValor2() + "''");
						}
					}
				}
			}
		}
		return retorno.toString();
	}

}
